//
//  Simulation.h
//  phy_four
//
//  Created by Snir Gazit on 3/12/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#ifndef phy_four_Simulation_h
#define phy_four_Simulation_h

#include "../HelpLibs/def.h"
#include "Lattice.h"
#include "Move.h"
#include "Measure.h"
#include "../HelpLibs/RandomGen.h"
#include "../HelpLibs/QmcParameters.h"
#include "../HelpLibs/pugixml/pugixml.hpp"
#include "boost/chrono.hpp"
#include <gsl/gsl_sf_hyperg.h>
#include <gsl/gsl_sf_gamma.h>
#include <iostream>
#include "../HelpLibs/InputFile.h"

double calcWR(double mu, double U, int m);
void calcWeight(double muIn, double UIn, double g, int maxBond,
		ostream &outFile, BoltzWeightType &weightR);

// Worm Algorithm

class OnModel {
	// Params
	QmcParameters qmcParameters_;
	// Configuration
	Lattice lat_;
	// Moves
	ShiftMove<Site::XYBondData> shiftMoveXY_;
	JumpMove<Site::XYBondData> jumpMoveXY_;
	//CreateMove<Site::XYBondData> createMoveXY_;
	//RemoveMove<Site::XYBondData> removeMoveXY_;
	SwitchMove<Site::XYBondData> switchMoveXY_;
	ShiftMove<Site::IsingBondData> shiftMoveIsing_;
	JumpMove<Site::IsingBondData> jumpMoveIsing_;
	//CreateMove<Site::IsingBondData> createMoveIsing_;
	// RemoveMove<Site::IsingBondData>removeMoveIsing_;
	SwitchMove<Site::IsingBondData> switchMoveIsing_;
	// Measurements
	Measurements measures_;
	// Random Number Engine
	MTGen eng_;
	// Draw Next Move
	DiscreteVariable openClosedSwitch_;
	// LoopType
	BinomialVariable chooseLoopType_;
	// OufPutFile
	ofstream outFile_;
	// Loop Type
public:
	~OnModel();
	void init(QmcParameters &qmcParameters);
	bool run();
	void thermalize();
	bool checkNotDone();
	void nextMove();
	void dump(bool final);
	void read();
};

// WormLoop Algorithm

class OnModelLoop {
	typedef Site::XYBondData XYBondData;
	typedef Site::IsingBondData IsingBondData;
	// Params
	QmcParameters qmcParameters_;
	// Configuration
	Lattice lat_;
	// Moves
	CreateLoopMove<XYBondData> CreateLoopMoveXY_;
	CreateLoopMove<IsingBondData> CreateLoopMoveIsing_;
	// Measurements
	Measurements measures_;
	// Random Number Engine
	MTGen eng_;
	// OufPutFile
	ofstream outFile_;
	// LoopType
	BinomialVariable chooseLoopType_;
	// Worm Length
	acc wormLengthXY_, wormLengthIsing_;
	// BoltzWeight
	BoltzWeightType boltzWeight_;
public:
	~OnModelLoop();
	void init(QmcParameters &qmcParameters);
	void setCoupeling(double g);
	bool run();
	void thermalize();
	void simulatedAnnealing();
	bool checkNotDone();
	void nextMove();
	void dump(bool final);
	void read();
};
#endif
